package com.cskaoyan.javase._1interface._1basic;

/**
 * 接口的自身特点以及成员特点
 * 接口的特点我们主要研究以下方面:
 *      1.接口的声明特点
 *          接口是抽象的,接口不能创建对象,接口声明的语法中
 *          本身就隐含了关键字"abstract"
 *          这个"abstract"关键字不要写出来
 *
 *          接口定义出来就是为了实现的,所以接口不能用final修饰
 *
 *      2.接口的命名格式
 *          接口的命名没有统一的格式,也没有固定的特殊格式
 *          有些程序员,喜欢在接口名之前,加"I"以表示这是一个接口
 *          比如:
 *          "ITest","IDemo"
 *
 *      3.接口的实现类的书写格式
 *          接口的实现类,推荐使用"接口名 + Impl"的形式
 *          有些程序员喜欢在接口的所在包下,新增一个"impl"包
 *          用来存放接口的实现类,类名是"接口名 + Impl"
 *
 *      4.接口成员特点
 *          1.变量
 *              成员变量
 *              静态成员变量
 *              全局常量
 *          接口中可以定义变量,但是接口中定义的变量,全部默认被"public static final"修饰
 *          接口中只能定义全局常量!!
 *          注:
 *              1.public的访问权限是隐含的,且访问权限不可更改.
 *                  实际上接口中所有能够定义的结构,都是public修饰的,都是不可更改权限的
 *
 *              2.public static final是隐含,不要写出来.
 *                  接口中定义全局常量,应该直接写数据类型 常量名 = 赋值即可.
 *
 *              3.接口中不允许定义静态代码块,所以接口中的全局常量必须显式赋值.
 *
 *              4.接口多数情况下表示对行为的抽象,实现接口表示功能的扩展
 *                  所以99%的接口中,都没有全局常量
 *                  只要当,你认为,接口的所有实现类都需要一个全局常量时,才考虑在接口中定义全局常量.
 *
 *          2.方法
 *              接口中的方法默认都是"public abstract"修饰的抽象方法
 *              注:
 *                  1.在java8之前,接口中只有抽象方法,在Java8及以后,接口中允许出现实现方法.
 *                  2.接口中的方法不要写出隐含的"public abstract",只要写返回值类型方法名等结构即可.
 *                  3.接口中的抽象方法和抽象类中的抽象方法一样,同样是占位作用,普通类实现接口,必须实现
 *                      接口中的所有抽象方法.
 *                      接口中的抽象方法是用于制定标准和规范
 *                  4.一个接口的定义在绝大多数情况下都是十分简陋的,都是抽象方法.
 *
 *          3.构造器
 *              思考: 接口有没有构造器?
 *              接口不能创建对象,并且接口中也没有成员变量需要赋值,所以接口不需要构造器,也没有构造器
 *
 *              思考: 接口没有构造器,那么接口子类对象初始化中super()该指向谁呢?
 *              指向父类,如果有明确的直接父类,就指向这个直接父类
 *              否者就指向Object
 *
 *              思考: 接口有没有继承Object呢?
 *              接口确实继承了Object,但实际没有意义
 *              因为所有接口的实现类,肯定也继承Object
 *
 *          4.代码块
 *              接口没有静态代码块
 *              接口没有构造器,也没有构造代码块
 *
 * 总结:
 *      接口和class大不相同
 *      只能定义全局常量和抽象方法(Java8之前)
 *      实际开发中,接口绝大多数情况下,都只会定义抽象方法.
 *
 *
 * 接口的子类(实现类):
 *      1.普通类,必须实现接口中的所有抽象方法
 *      2.抽象类,无需实现抽象方法,也可以选择性的实现某些.
 *      3.接口.接口的"子类"可以是接口
 *          但是注意接口是继承接口,而不是实现接口
 *          并且接口的继承,可以多继承
 *
 * 总结一下，接口和类的继承/实现的规则：
 *      1.继承（extends）是不能跨越种族的:
 *          类和类继承，接口和接口继承，接口和类之间没有继承关系。
 *          a.普通类继承一个抽象类，需要实现里面的所有抽象方法。
 *          b.抽象类继承一个抽象类，按需实现里面的抽象方法。
 *          c.抽象类继承一个普通类，是可以的。(但是这种情况很少见,当然抽象类肯定也继承Object)
 *          d.接口在继承一个接口后，会得到接口的所有抽象方法。
 *          注: 类的继承是单继承的，接口的继承是多继承的。
 *
 *      2.实现（implements），必须发现在类与接口之间，接口和类是没有任何关系的。
 *          类实现接口,接口和类没有直接关系.(接口不能继承类,也不能实现类)
 *          a.普通类实现接口，必须实现所有抽象方法
 *          b.抽象类实现接口，按需实现抽象方法
 *
 * @since 11:32
 * @author wuguidong@cskaoyan.onaliyun.com
 */
// Modifier 'abstract' is redundant for interfaces
public interface ITest {
    // 接口中定义变量
    // Variable 'a' might not have been initialized
    // int a;
    // Variable 'b' might not have been initialized
    // static int b;

    // Modifier 'static' is redundant for interface fields
    // Modifier 'final' is redundant for interface fields
    // static final int C = 10;

    // 接口中定义全局常量的正确姿势:
    int NUM = 100;

    // 接口中可以定义抽象方法
    // public abstract void test();

    // 接口中定义抽象方法的正确姿势:
    void test();

    // static{}
    // {}
}

// 实际开发中,见到的绝大多数接口
interface IA {
    // 建议大家写抽象方法时,写上一句简单明了的注释
    void test();

    int test(int a);

    String test2();
}

interface IC {
}

interface IB extends IA,IC {
}


abstract class AbstractA implements IA {

}
/*
class A {
    // Variable 'a' might not have been initialized
    final int a;
}*/
